home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / faq / computer-lang / ada / programming / part3.z / part3
Internet Message Format  |  1999-01-01  |  39KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!newsfeed.internetmci.com!howland.reston.ans.net!surfnet.nl!swsbe6.switch.ch!swidir.switch.ch!epflnews!dinews.epfl.ch!Magnus.Kempe
  2. From: Magnus.Kempe@di.epfl.ch (Magnus Kempe)
  3. Newsgroups: comp.lang.ada,comp.answers,news.answers
  4. Subject: Ada FAQ: Programming with Ada (part 3 of 4)
  5. Followup-To: poster
  6. Date: 30 May 1996 17:09:27 GMT
  7. Organization: None
  8. Lines: 835
  9. Sender: magnus@lglsun4.epfl.ch (Magnus Kempe)
  10. Approved: news-answers-request@MIT.EDU
  11. Distribution: world
  12. Message-ID: <4okko7$idt@disunms.epfl.ch>
  13. Reply-To: Magnus.Kempe@di.epfl.ch (Magnus Kempe)
  14. NNTP-Posting-Host: lglsun4.epfl.ch
  15. Mime-Version: 1.0
  16. Content-Type: text/plain; charset=iso-8859-1
  17. Content-Transfer-Encoding: 8bit
  18. Summary: Ada Programmer's Frequently Asked Questions (and answers),
  19.            part 3 of 4.
  20.          Please read before posting.
  21. Keywords: advanced language, artificial languages, computer software,
  22.           data processing, programming languages, Ada
  23. Xref: senator-bedfellow.mit.edu comp.lang.ada:45675 comp.answers:18998 news.answers:73084
  24.  
  25. Archive-name: computer-lang/Ada/programming/part3
  26. Comp-lang-ada-archive-name: programming/part3
  27. Posting-Frequency: monthly
  28. Last-modified: 22 May 1996
  29. Last-posted: 23 April 1996
  30.  
  31.                                Ada Programmer's
  32.                        Frequently Asked Questions (FAQ)
  33.  
  34.    IMPORTANT NOTE: No FAQ can substitute for real teaching and
  35.    documentation. There is an annotated list of Ada books in the
  36.    companion comp.lang.ada FAQ.
  37.  
  38.     Recent changes to this FAQ are listed in the first section after the table
  39.     of contents. This document is under explicit copyright.
  40.  
  41. This is part 3 of a 4-part posting; part 1 contains the table of contents.
  42. Part 2 begins with question 5.
  43. Part 4 begins with question 9.
  44. Parts 1 and 2 should be the previous postings in this thread.
  45. Part 4 should be the next posting in this thread.
  46.  
  47.  
  48. 6: Ada Numerics
  49.  
  50.  
  51. 6.1: Where can I find anonymous ftp sites for Ada math packages? In particular
  52. where are the random number generators?
  53.  
  54.  
  55.    ftp.rational.com
  56.           Freeware version of the ISO math packages on Rational's FTP
  57.           server. It's a binding over the C Math library, in
  58.           public/apex/freeware/math_lib.tar.Z
  59.  
  60.    archimedes.nosc.mil
  61.           Stuff of high quality in pub/ada The random number generator
  62.           and random deviates are recommended. These are mirrored at the
  63.           next site, wuarchive.
  64.  
  65.    wuarchive.wustl.edu
  66.           Site of PAL, the Public Ada Library: math routines scattered
  67.           about in the directories under languages/ada in particular, in
  68.           subdirectory swcomps
  69.  
  70.    source.asset.com
  71.           This is not an anonymous ftp site for math software. What you
  72.           should do is log on anonymously under ftp, and download the
  73.           file asset.faq from the directory pub. This will tell you how
  74.           to get an account.
  75.  
  76.    ftp.cs.kuleuven.ac.be
  77.           Go to directory pub/Ada-Belgium/cdrom. There's a collection of
  78.           math intensive software in directory swcomps. Mirrors some of
  79.           PAL at wuarchive.wustl.edu.
  80.  
  81.    sw-eng.falls-church.va.us
  82.           Go to directory public/AdaIC/source-code/bindings/ADAR-bindings
  83.           to find extended-precision decimal arithmetic (up to 18
  84.           digits). Includes facilities for COBOL-like formatted output.
  85.  
  86.  
  87. 6.2: How can I write portable code in Ada 83 using predefined types like Float
  88. and Long_Float? Likewise, how can I write portable code that uses Math
  89. functions like Sin and Log that are defined for Float and Long_Float?
  90.  
  91.    (from Jonathan Parker)
  92.  
  93.    Ada 83 was slow to arrive at a standard naming convention for
  94.    elementary math functions and complex numbers. Furthermore, you'll
  95.    find that some compilers call the 64-bit floating point type
  96.    Long_Float; other compilers call it Float. Fortunately, it is easy to
  97.    write programs in Ada that are independent of the naming conventions
  98.    for floating point types and independent of the naming conventions of
  99.    math functions defined on those types.
  100.  
  101.    One of the cleanest ways is to make the program generic:
  102.  
  103.      generic
  104.        type Real is digits <>;
  105.        with function Arcsin (X : Real) return Real is <>;
  106.        with function    Log (X : Real) return Real is <>;
  107.        --  This is the natural log, inverse of Exp(X), sometimes written Ln(X).
  108.      package Example_1 is
  109.        ...
  110.      end Example_1;
  111.  
  112.  
  113.    So the above package doesn't care what the name of the floating point
  114.    type is, or what package the Math functions are defined in, just as
  115.    long as the floating point type has the right attributes (precision
  116.    and range) for the algorithm, and likewise the functions. Everything
  117.    in the body of Example_1 is written in terms of the abstract names,
  118.    Real, Arcsin, and Log, even though you instantiate it with compiler
  119.    specific names that can look very different:
  120.  
  121.       package Special_Case is new Example_1 (Long_Float, Asin, Ln);
  122.  
  123.  
  124.    The numerical algorithms implemented by generics like Example_1 can
  125.    usually be made to work for a range of floating point precisions. A
  126.    well written program will perform tests on Real to reject
  127.    instantiations of Example_1 if the floating points type is judged
  128.    inadequate. The tests may check the number of digits of precision in
  129.    Real (Real'Digits) or the range of Real (Real'First, Real'Last) or the
  130.    largest exponent of the set of safe numbers (Real'Safe_Emax), etc.
  131.    These tests are often placed after the begin statement of package
  132.    body, as in:
  133.  
  134.      package body Example_1 is
  135.        ...
  136.      begin
  137.        if (Real'Machine_Mantissa > 60) or (Real'Machine_Emax < 256) then
  138.          raise Program_Error;
  139.        end if;
  140.      end Example_1;
  141.  
  142.  
  143.    Making an algorithm as abstract as possible, (independent of data
  144.    types as much as possible) can do a lot to improve the quality of the
  145.    code. Support for abstraction is one of the many things Ada-philes
  146.    find so attractive about the language. The designers of Ada 95
  147.    recognized the value of abstraction in the design of numeric
  148.    algorithms and have generalized many of the features of the '83 model.
  149.    For example, no matter what floating point type you instantiate
  150.    Example_1 with, Ada 95 provides you with functions for examining the
  151.    exponent and the mantissas of the numbers, for truncating, determining
  152.    exact remainders, scaling exponents, and so on. (In the body of
  153.    Example_1, and in its spec also of course, these functions are
  154.    written, respectively: Real'Exponent(X), Real'Fraction(X),
  155.    Real'Truncation(X), Real'Remainder(X,Y), Real'Scaling(X, N). There are
  156.    others.) Also, in package Example_1, Ada 95 lets you do the arithmetic
  157.    on the base type of Real (called Real'Base) which is liable to have
  158.    greater precision and range than type Real.
  159.  
  160.    It is rare to see a performance loss when using generics like this.
  161.    However, if there is an unacceptable performance hit, or if generics
  162.    cannot be used for some other reason, then subtyping and renaming will
  163.    do the job. Here is an example of renaming:
  164.  
  165.      with Someones_Math_Lib;
  166.      procedure Example_2 is
  167.  
  168.        subtype Real is Long_Float;
  169.  
  170.        package  Math renames Someones_Math_Lib;
  171.        function Arcsin(X : Real) return Real renames Math.Asin
  172.        function   Log (X : Real) return Real renames Math.  Ln;
  173.  
  174.        --  Everything beyond this point is abstract with respect to
  175.        --  the names of the floating point (Real), the functions (Arcsin
  176.        --  and Log), and the package that exported them (Math).
  177.        ...
  178.      end Example_2;
  179.  
  180.  
  181.    I prefer to make every package and subprogram (even test procedures)
  182.    as compiler independent and machine portable as possible. To do this
  183.    you move all of the renaming of compiler dependent functions and all
  184.    of the "withing" of compiler dependent packages to a single package.
  185.    In the example that follows, its called Math_Lib_8. Math_Lib_8 renames
  186.    the 8-byte floating point type to Real_8, and makes sure the math
  187.    functions follow the Ada 95 standard, at least in name. In this
  188.    approach Math_Lib_8 is the only compiler dependent component.
  189.  
  190.    There are other, perhaps better, ways also. See for example, "Ada In
  191.    Action", by Do-While Jones for a generic solution.
  192.  
  193.    Here's the spec of Math_Lib_8, which is a perfect subset of package
  194.    Math_Env_8, available by FTP in file
  195.    ftp://lglftp.epfl.ch/pub/Ada/FAQ/math_env_8.ada
  196.  
  197.  
  198. --***************************************************************
  199. -- Package Math_Lib_8
  200. --
  201. -- A minimal math package for Ada 83: creates a standard interface to vendor
  202. -- specific double-precision (8-byte) math libraries.  It renames the 8 byte
  203. -- Floating point type to Real_8, and uses renaming to create
  204. -- (Ada 95) standard names for Sin, Cos, Log, Sqrt, Arcsin, Exp,
  205. -- and Real_8_Floor, all defined for Real_8.
  206. --
  207. -- A more ambitious but perhaps less efficient
  208. -- package would wrap the compiler specific functions in function calls, and
  209. -- do error handling on the arguments to Ada 95 standards.
  210. --
  211. -- The package assumes that Real_8'Digits > 13, and that
  212. -- Real_8'Machine_Mantissa < 61.  These are asserted after the
  213. -- begin statement in the body.
  214. --
  215. -- Some Ada 83 compilers don't provide Arcsin, so a rational-polynomial+
  216. -- Newton-Raphson method Arcsin and Arccos pair are provided in the body.
  217. --
  218. -- Some Ada 83 compilers don't provide for truncation of 8 byte floats.
  219. -- Truncation is provided here in software for Compilers that don't have it.
  220. -- The Ada 95 function for truncating (toward neg infinity) is called 'Floor.
  221. --
  222. -- The names of the functions exported below agree with the Ada9X standard,
  223. -- but not, in all likelihood the semantics.   It is up to the user to
  224. -- be careful...to do his own error handling on the arguments, etc.
  225. -- The performance of these function can be non-portable,
  226. -- but in practice they have their usual meanings unless you choose
  227. -- weird arguments.  The issues are the same with most math libraries.
  228. --***************************************************************
  229.  
  230. --with Math_Lib;                                  -- Meridian DOS Ada.
  231.   with Long_Float_Math_Lib;                       -- Dec VMS
  232. --with Ada.Numerics.Generic_Elementary_Functions; -- Ada9X
  233. package Math_Lib_8 is
  234.  
  235. --subtype Real_8 is Float;                        -- Meridian 8-byte Real
  236.   subtype Real_8 is Long_Float;                   -- Dec VMS  8-byte Real
  237.  
  238.  --package Math renames Math_Lib;                 -- Meridian DOS Ada
  239.    package Math renames Long_Float_Math_Lib;      -- Dec VMS
  240.  --package Math is new Ada.Numerics.Generic_Elementary_Functions(Real_8);
  241.  
  242.    --  The above instantiation of the Ada.Numerics child package works on
  243.    --  GNAT, or any other Ada 95 compiler.  Its here if you want to use
  244.    --  an Ada 95 compiler to compile Ada 83 programs based on this package.
  245.  
  246.    function Cos (X : Real_8) return Real_8 renames Math.Cos;
  247.    function Sin (X : Real_8) return Real_8 renames Math.Sin;
  248.    function Sqrt(X : Real_8) return Real_8 renames Math.Sqrt;
  249.    function Exp (X : Real_8) return Real_8 renames Math.Exp;
  250.  
  251.  --function Log (X : Real_8) return Real_8 renames Math.Ln;        -- Meridian
  252.    function Log (X : Real_8) return Real_8 renames Math.Log;       -- Dec VMS
  253.  --function Log (X : Real_8) return Real_8 renames Math.Log;       -- Ada 95
  254.  
  255.  --function Arcsin (X : Real_8) return Real_8 renames Math.Asin;   -- Dec VMS
  256.  --function Arcsin (X : Real_8) return Real_8 renames Math.Arcsin; -- Ada 95
  257.    function Arcsin (X : Real_8) return Real_8;
  258.    --  Implemented in the body.  Should work with any compiler.
  259.  
  260.  --function Arccos (X : Real_8) return Real_8 renames Math.Acos;   -- Dec VMS
  261.  --function Arccos (X : Real_8) return Real_8 renames Math.Arccos; -- Ada 95
  262.    function Arccos (X : Real_8) return Real_8;
  263.    --  Implemented in the body.  Should work with any compiler.
  264.  
  265.  --function Real_8_Floor (X : Real_8) return Real_8 renames Real_8'Floor;-- 95
  266.    function Real_8_Floor (X : Real_8) return Real_8;
  267.    --  Implemented in the body.  Should work with any compiler.
  268.  
  269. end Math_Lib_8;
  270.  
  271.  
  272. 6.3: Is Ada any good at numerics, and where can I learn more about it?
  273.  
  274.    First of all, a lot of people find the general Ada philosophy
  275.    (modularity, strong-typing, readable syntax, rigorous definition and
  276.    standardization, etc.) to be a real benefit in numerical programming,
  277.    as well as in many other types of programming. But Ada --and
  278.    especially Ada 95-- was also designed to meet the special requirements
  279.    of number-crunching applications.
  280.  
  281.    The following sketches out some of these features. Hopefully a little
  282.    of the flavor of the Ada philosophy will get through, but the best
  283.    thing you can do at present is to read the two standard reference
  284.    documents, the Ada 95 Rationale and Reference Manual. Below the GNU
  285.    Ada 95 compiler is referred to several times. This compiler can be
  286.    obtained by anonymous FTP from cs.nyu.edu, and at mirror sites
  287.    declared in the README file of directory pub/gnat.
  288.  
  289.    1. Machine portable floating point declarations. (Ada 83 and Ada 95)
  290.           If you declare "type Real is digits 14", then type Real will
  291.           guarantee you (at least) 14 digits of precision independently
  292.           of machine or compiler. In this case the base type of type Real
  293.           will usually be the machine's 8-byte floating point type. If an
  294.           appropriate base type is unavailable (very rare), then the
  295.           declaration is rejected by the compiler.
  296.  
  297.    2. Extended precision for initialization of floating point. (Ada 83
  298.           and Ada 95)
  299.           Compilers are required to employ
  300.           extended-precision/rational-arithmetic routines so that
  301.           floating point variables and constants can be correctly
  302.           initialized to their full precision.
  303.  
  304.    3. Generic packages and subprograms. (Ada 83 and Ada 95)
  305.           Algorithms can be written so that they perform on abstract
  306.           representations of the data structure. Support for this is
  307.           provided by Ada's generic facilities (what C++ programmers
  308.           would call templates).
  309.  
  310.    4. User-defined operators and overloaded subprograms. (Ada 83 and Ada
  311.           95)
  312.           The programmer can define his own operators (functions like
  313.           "*", "+", "abs", "xor", "or", etc.) and define any number of
  314.           subprograms with the same name (provided they have different
  315.           argument profiles).
  316.  
  317.    5. Multitasking. (Ada 83 and Ada 95)
  318.           Ada facilities for concurrent programming (multitasking) have
  319.           traditionally found application in simulations and
  320.           distributed/parallel programming. Ada tasking is an especially
  321.           useful ingredient in the Ada 95 distributed programming model,
  322.           and the combination of the two makes it possible to design
  323.           parallel applications that have a high degree of operating
  324.           system independence and portability. (More on this in item 6
  325.           below.)
  326.  
  327.    6. Direct support for distributed/parallel computing in the language.
  328.           (Ada 95)
  329.           Ada 95 is probably the first internationally standardized
  330.           language to combine in the same design complete facilities for
  331.           multitasking and parallel programming. Communication between
  332.           the distributed partitions is via synchronous and asynchronous
  333.           remote procedure calls.
  334.  
  335.           Good discussion, along with code examples, is found in the
  336.           Rationale, Part III E, and in the Ada 95 Reference Manual,
  337.           Annex E. See also "Ada Letters", Vol. 13, No. 2 (1993), pp. 54
  338.           and 78, and Vol. 14, No. 2 (1994), p. 80. (Full support for
  339.           these features is provided by compilers that conform to the Ada
  340.           95 distributed computing Annex. This conformance is optional,
  341.           but for instance GNAT, the Gnu Ada 95 compiler, will meet these
  342.           requirements.)
  343.  
  344.    7. Attributes of floating point types. (Ada 83 and Ada 95)
  345.           For every floating point type (including user defined types),
  346.           there are built-in functions that return the essential
  347.           characteristics of the type. For example, if you declare "type
  348.           Real is digits 15" then you can get the max exponent of objects
  349.           of type Real from Real'Machine_Emax. Similarly, the size of the
  350.           Mantissa, the Radix, the largest Real, and the Rounding policy
  351.           of the arithmetic are given by Real'Machine_Mantissa,
  352.           Real'Machine_Radix, Real'Last, and Real'Machine_Rounds. There
  353.           are many others.
  354.  
  355.           (See Ada 95 Reference Manual, clause 3.5, subclause 3.5.8 and
  356.           A.5.3, as well as Part III sections G.2 and G.4.1 of the Ada 95
  357.           Rationale.)
  358.  
  359.    8. Attribute functions for floating point types. (Ada 95)
  360.           For every floating point type (including user defined types),
  361.           there are built-in functions that operate on objects of that
  362.           type. For example, if you declare "type Real is digits 15" then
  363.           Real'Remainder (X, Y) returns the exact remainder of X and Y: X
  364.           - n*Y where n is the integer nearest X/Y. Real'Truncation(X),
  365.           Real'Max(X,Y), Real'Rounding(X) have the usual meanings.
  366.           Real'Fraction(X) and Real'Exponent(X) break X into mantissa and
  367.           exponent; Real'Scaling(X, N) is exact scaling: multiplies X by
  368.           Radix**N, which can be done by incrementing the exponent by N,
  369.           etc. (See citations in item 7.)
  370.  
  371.    9. Modular arithmetic on integer types. (Ada 95)
  372.           If you declare "type My_Unsigned is mod N", for arbitrary N,
  373.           then arithmetic ("*", "+", etc.) on objects of type My_Unsigned
  374.           returns the results modulo N. Boolean operators "and", "or",
  375.           "xor", and "not" are defined on the objects as though they were
  376.           arrays of bits (and likewise return results modulo N). For N a
  377.           power of 2, the semantics are similar to those of C unsigned
  378.           types.
  379.  
  380.    10. Generic elementary math functions for floating point types. (Ada
  381.           95)
  382.           Required of all compilers, and provided for any floating point
  383.           type: Sqrt, Cos, Sin, Tan, Cot, Exp, Sinh, Cosh, Tanh, Coth,
  384.           and the inverse functions of each of these, Arctan, Log,
  385.           Arcsinh, etc. Also, X**Y for floating point X and Y. Compilers
  386.           that conform to the Numerics Annex meet additional accuracy
  387.           requirements.
  388.  
  389.           (See subclause A.5.1 of the Ada 95 RM, and Part III, Section
  390.           A.3 of the Ada 95 Rationale.)
  391.  
  392.    11. Complex numbers. (Ada 95)
  393.           Fortran-like, but with a new type called Imaginary. Type
  394.           "Imaginary" allows programmers to write expressions in such a
  395.           way that they are easier to optimize, more readable and appear
  396.           in code as they appear on paper. Also, the ability to declare
  397.           object of pure imaginary type reduces the number of cases in
  398.           which premature type conversion of real numbers to complex
  399.           causes floating point exceptions to occur. (Provided by
  400.           compilers that conform to the Numerics Annex. The Gnu Ada 95
  401.           compiler supports this annex, so the source code is freely
  402.           available.)
  403.  
  404.    12. Generic elementary math functions for complex number types. (Ada
  405.           95)
  406.           Same functions supported for real types, but with complex
  407.           arguments. Standard IO is provided for floating point types and
  408.           Complex types. (Only required of compilers that support the
  409.           Numerics Annex, like Gnu Ada.)
  410.  
  411.    13. Pseudo-random numbers for discrete and floating point types. (Ada
  412.           95)
  413.           A floating point pseudo-random number generator (PRNG) provides
  414.           output in the range 0.0 .. 1.0. Discrete: A generic PRNG
  415.           package is provided that can be instantiated with any discrete
  416.           type: Boolean, Integer, Modular etc. The floating point PRNG
  417.           package and instances of the (discrete) PRNG package are
  418.           individually capable of producing independent streams of random
  419.           numbers. Streams may be interrupted, stored, and resumed at
  420.           later times (generally an important requirement in
  421.           simulations). In Ada it is considered important that multiple
  422.           tasks, engaged for example in simulations, have easy access to
  423.           independent streams of pseudo random numbers. The Gnu Ada 95
  424.           compiler provides the cryptographically secure X**2 mod N
  425.           generator of Blum, Blum and Shub.
  426.  
  427.           (See subclause A.5.2 of the Ada 95 Reference Manual, and part
  428.           III, section A.3.2 of the Ada Rationale.)
  429.  
  430.    14. Well-defined interfaces to Fortran and other languages. (Ada 83
  431.           and Ada 95)
  432.           It has always been a basic requirement of the language that it
  433.           provide users a way to interface Ada programs with foreign
  434.           languages, operating system services, GUI's, etc. Ada can be
  435.           viewed as an interfacing language: its module system is
  436.           composed of package specifications and separate package bodies.
  437.           The package specifications can be used as strongly-type
  438.           interfaces to libraries implemented in foreign languages, as
  439.           well as to package bodies written in Ada. Ada 95 extends on
  440.           these facilities with package interfaces to the basic data
  441.           structures of C, Fortran, and COBOL and with new pragmas. For
  442.           example, "pragma Convention(Fortran, M)" tells the compiler to
  443.           store the elements of matrices of type M in the Fortran
  444.           column-major order. (This pragma has already been implemented
  445.           in the Gnu Ada 95 compiler. Multi- lingual programming is also
  446.           a basic element of the Gnu compiler project.) As a result,
  447.           assembly language BLAS and other high performance linear
  448.           algebra and communications libraries will be accessible to Ada
  449.           programs.
  450.  
  451.           (See Ada 95 Reference Manual: clause B.1 and B.5 of Annex B,
  452.           and Ada 95 Rationale: Part III B.)
  453.  
  454.  
  455. 6.4: How do I get Real valued and Complex valued math functions in Ada 95?
  456.  
  457.    (from Jonathan Parker)
  458.  
  459.    Complex type and functions are provided by compilers that support the
  460.    numerics Annex. The packages that use Float for the Real number and
  461.    for the Complex number are:
  462.  
  463.      Ada.Numerics.Elementary_Functions;
  464.      Ada.Numerics.Complex_Types;
  465.      Ada.Numerics.Complex_Elementary_Functions;
  466.  
  467.  
  468.    The packages that use Long_Float for the Real number and for the
  469.    Complex number are:
  470.  
  471.      Ada.Numerics.Long_Elementary_Functions;
  472.      Ada.Numerics.Long_Complex_Types;
  473.      Ada.Numerics.Long_Complex_Elementary_Functions;
  474.  
  475.  
  476.    The generic versions are demonstrated in the following example. Keep
  477.    in mind that the non-generic packages may have been better tuned for
  478.    speed or accuracy. In practice you won't always instantiate all three
  479.    packages at the same time, but here is how you do it:
  480.  
  481.      with Ada.Numerics.Generic_Complex_Types;
  482.      with Ada.Numerics.Generic_Elementary_Functions;
  483.      with Ada.Numerics.Generic_Complex_Elementary_Functions;
  484.  
  485.      procedure Do_Something_Numerical is
  486.  
  487.        type Real_8 is digits 15;
  488.  
  489.        package Real_Functions_8 is
  490.          new Ada.Numerics.Generic_Elementary_Functions (Real_8);
  491.  
  492.        package Complex_Nums_8 is
  493.          new Ada.Numerics.Generic_Complex_Types (Real_8);
  494.  
  495.        package Complex_Functions_8 is
  496.          new Ada.Numerics.Generic_Complex_Elementary_Functions
  497.            (Complex_Nums_8);
  498.  
  499.        use Real_Functions_8, Complex_Nums_8, Complex_Functions_8;
  500.        ...
  501.        ... -- Do something
  502.        ...
  503.      end Do_Something_Numerical;
  504.  
  505.  
  506. 6.5: What libraries or public algorithms exist for Ada?
  507.  
  508.    An Ada version of Fast Fourier Transform is available. It's in
  509.    journal "Computers & Mathematics with Applications," vol. 26, no. 2,
  510.    pp. 61-65, 1993, with the title:
  511.  
  512.    "Analysis of an Ada Based Version of Glassman's General N Point Fast
  513.    Fourier Transform"
  514.  
  515.    The package is now available in the AdaNET repository, object #: 6728,
  516.    in collection: Transforms. If you're not an AdaNET user, contact Peggy
  517.    Lacey (lacey@rbse.mountain.net).
  518.  
  519.      _________________________________________________________________
  520.  
  521.  
  522. 7: Efficiency of Ada Constructs
  523.  
  524.  
  525. 7.1: How much extra overhead do generics have?
  526.  
  527.    If you overgeneralize the generic, there will be more work to do for
  528.    the compiler. How do you know when you have overgeneralized? For
  529.    instance, passing arithmetic operations as parameters is a bad sign.
  530.    So are boolean or enumeration type generic formal parameters. If you
  531.    never override the defaults for a parameter, you probably
  532.    overengineered.
  533.  
  534.    Code sharing (if implemented and requested) will cause an additional
  535.    overhead on some calls, which will be partially offset by improved
  536.    locality of reference. (Translation, code sharing may win most when
  537.    cache misses cost most.) If a generic unit is only used once in a
  538.    program, code sharing always loses.
  539.  
  540.    R.R. Software chose code sharing as the implementation for generics
  541.    because 2 or more instantiations of Float_Io in a macro implementation
  542.    would have made a program too large to run in the amount of memory
  543.    available on the PC machines that existed in 1983 (usually a 128k or
  544.    256k machine).
  545.  
  546.    Generics in Ada can also result in loss of information which could
  547.    have helped the optimizer. Since the compiler is not restricted by Ada
  548.    staticness rules within a single module, you can often avoid penalties
  549.    by declaring (or redeclaring) bounds so that they are local:
  550.  
  551.      package Global is
  552.        subtype Global_Int is
  553.          Integer range X..Y;
  554.  
  555.        ...
  556.      end Global;
  557.  
  558.  
  559.      with Global;
  560.      package Local is
  561.        subtype Global_Int is
  562.          Global.Global_Int;
  563.  
  564.        package Some_Instance is
  565.          new Foo (Global_Int);
  566.  
  567.        ...
  568.      end Local;
  569.  
  570.  
  571.    Ada rules say that having the subtype redeclared locally does not
  572.    affect staticness, but on a few occasions optimizers have been caught
  573.    doing a much better job. Since optimizers are constantly changing,
  574.    they may have been caught just at the wrong time.
  575.  
  576.  
  577. 7.2: How does Ada compare to other languages in efficiency of code?
  578.  
  579.    Ada vs. C: An analysis at Tartan found that Ada and C had fairly
  580.    similar performance, with Ada having a slight edge. See "C vs. Ada:
  581.    Arguing Performance Religion" by David Syiek, ACM Ada Letters, Nov/Dec
  582.    1995 (Volume XV Number 6), pp. 67-69.
  583.  
  584.    Ada vs. assembly language: There is a documented case where an Ada
  585.    compiler and a novice Ada programmer did better than experienced
  586.    assembly language programmers. See "Ada Whips Assembly" by Elam and
  587.    Lawlis, Crosstalk, March 1992. Published by the Software Technology
  588.    Support Center, Hill Air Force Base, Utah: Defense Printing Service.
  589.  
  590.      _________________________________________________________________
  591.  
  592. 8: Advanced Programming Techniques with Ada
  593.  
  594.  
  595. 8.1: How can I redefine the assignment operation?
  596.  
  597.    The general answer is: use controlled types (RM95-7.6).
  598.  
  599.    For detailed explanations, read the following papers:
  600.      * "Tips and Tidbits #1: User Defined Assignment" by Brad Balfour,
  601.        HTML at http://www.acm.org/~bbalfour/tips_no_1.html
  602.      * "Abstract Data Types Are Under Full Control with Ada 9X" by Magnus
  603.        Kempe, Postscript file at
  604.        http://lglwww.epfl.ch/Ada/Resources/Papers/OO/ADT_Control-revised.ps
  605.  
  606.  
  607. 8.2: Does Ada have automatic constructors and destructors?
  608.  
  609.    Yes, controlled types have special, user-definable operations that
  610.    control the construction and destruction of objects and values of
  611.    those types (see question 8.1, above).
  612.  
  613.    (Also: Tucker Taft replies)
  614.    At least in Ada 9X, functions with controlling results are inherited
  615.    (even if overriding is required), allowing their use with dynamic
  616.    binding and class-wide types. In most other OOPs, constructors can
  617.    only be called if you know at compile time the "tag" (or equivalent)
  618.    of the result you want. In Ada 9X, you can use the tag determined by
  619.    the context to control dispatching to a function with a controlling
  620.    result. For example:
  621.  
  622.      type Set is abstract tagged private;
  623.      function  Empty return Set is abstract;
  624.      function  Unit_Set(Element : Element_Type) return Set is abstract;
  625.      procedure Remove(S : in out Set; Element : out Element_Type) is abstract;
  626.      function  Union(Left, Right : Set) return Set is abstract;
  627.   ...
  628.  
  629.      procedure Convert(Source : Set'Class; Target : out Set'Class) is
  630.        -- class-wide "convert" routine, can convert one representation
  631.        --   of a set into another, so long as both set types are
  632.        --   derived from "Set," either directly or indirectly.
  633.  
  634.        -- Algorithm:  Initialize Target to the empty set, and then
  635.        --             copy all elements from Source set to Target set.
  636.  
  637.         Copy_Of_Source : Set'Class := Source;
  638.         Element : Element_Type;
  639.      begin
  640.         Target := Empty;  -- Dispatching for Empty determined by Target'Tag.
  641.  
  642.         while Copy_Of_Source /= Empty loop
  643.                        -- Dispatching for Empty based on Copy_Of_Source'Tag
  644.  
  645.             Remove_Element(Copy_Of_Source, Element);
  646.  
  647.             Target := Union(Target, Unit_Set(Element));
  648.                        -- Dispatching for Unit_Set based on Target'Tag
  649.         end loop;
  650.      end Convert;
  651.  
  652.  
  653.    The functions Unit_Set and Empty are essentially "constructors" and
  654.    hence must be overridden in every extension of the abstract type Set.
  655.    However, these operations can still be called with a class-wide
  656.    expected type, and the controlling tag for the function calls will be
  657.    determined at run-time by the context, analogous to the kind of
  658.    (compile-time) overload resolution that uses context to disambiguate
  659.    enumeration literals and aggregates.
  660.  
  661.  
  662. 8.3: Should I stick to a one package, one type approach while writing Ada
  663. software?
  664.  
  665.    (Robb Nebbe responds)
  666.  
  667.    Offhand I can think of a couple of advantages arising from Ada's
  668.    separation of the concepts of type and module.
  669.  
  670.    Separation of visibility and inheritance allows a programmer to
  671.    isolate a derived type from the implementation details of its parent.
  672.    To put it another way information hiding becomes a design decision
  673.    instead of a decision that the programming language has already made
  674.    for you.
  675.  
  676.    Another advantage that came "for free" is the distinction between
  677.    subtyping and implementation inheritance. Since modules and types are
  678.    independent concepts the interaction of the facilities for information
  679.    hiding already present in Ada83 with inheritance provide an elegant
  680.    solution to separating subtyping from implementation inheritance. (In
  681.    my opinion more elegant than providing multiple forms of inheritance
  682.    or two distinct language constructs.)
  683.  
  684.  
  685. 8.4: What is the "Beaujolais Effect"?
  686.  
  687.    The "Beaujolais Effect" is detrimental, and language designers should
  688.    try to avoid it. But what is it?
  689.  
  690.    (from Tucker Taft)
  691.  
  692.    The term "Beaujolais Effect" comes from a prize (a bottle of
  693.    Beaujolais) offered by Jean Ichbiah during the original Ada design
  694.    process to anyone who could find a situation where adding or removing
  695.    a single "use" clause could change a program from one legal
  696.    interpretation to a different legal interpretation. (Or equivalently,
  697.    adding or removing a single declaration from a "use"d package.)
  698.  
  699.    At least one bottle was awarded, and if the offer was still open, a
  700.    few more might have been awarded during the Ada 9X process. However,
  701.    thanks to some very nice analysis by the Ada 9X Language Precision
  702.    Team (based at Odyssey Research Associates) we were able to identify
  703.    the remaining cases of this effect in Ada 83, and remove them as part
  704.    of the 9X process.
  705.  
  706.    The existing cases in Ada 83 had to do with implicit conversion of
  707.    expressions of a universal type to a non-universal type. The rules in
  708.    Ada 9X are subtly different, making any case that used to result in a
  709.    Beaujolais effect in Ada 83, illegal (due to ambiguity) in Ada 9X.
  710.  
  711.    The Beaujolais effect is considered "harmful" because it is expected
  712.    that during maintenance, declarations may be added or removed from
  713.    packages without being able to do an exhaustive search for all places
  714.    where the package is "use"d. If there were situations in the language
  715.    which resulted in Beaujolais effects, then certain kinds of changes in
  716.    "use"d packages might have mysterious effects in unexpected places.
  717.  
  718.    (from Jean D. Ichbiah)
  719.  
  720.    It is worth pointing that many popular languages have Beaujolais
  721.    effect: e.g. the Borland Pascal "uses" clause, which takes an
  722.    additive, layer-after-layer, interpretation of what you see in the
  723.    used packages (units) definitely exhibits a Beaujolais effect.
  724.  
  725.    Last time I looked at C++, my impression was that several years of
  726.    Beaujolais vintage productions would be required.
  727.  
  728.    For component-based software development, such effects are undesirable
  729.    since your application may stop working when you recompile it with the
  730.    new -- supposedly improved -- version of a component.
  731.  
  732.  
  733. 8.5: What about the "Ripple Effect"?
  734.  
  735.    (Tucker Taft explains)
  736.  
  737.    We have eliminated all remnants of the Beaujolais Effect, but we did
  738.    debate various instances of the "Ripple" effect during the language
  739.    revision process (apologies to Gallo Ripple Wine enthusiasts ;-).
  740.  
  741.    In brief, the (undesirable) Ripple effect was related to whether the
  742.    legality of a compilation unit could be affected by adding or removing
  743.    an otherwise unneeded "with" clause on some compilation unit on which
  744.    the unit depended, directly or indirectly.
  745.  
  746.    This issue came up at least twice. One when we were considering rules
  747.    relating to use of attributes like 'Address. In Ada 83 as interpreted
  748.    by the ARG, if a compilation unit contains a use of 'Address, then
  749.    there must be a "with" of package System somewhere in the set of
  750.    library unit specs "with"ed by the compilation unit (directly or
  751.    indirectly).
  752.  
  753.    In Ada 9X, we have eliminated this rule, as it was for some compilers
  754.    an unnecessary implementation burden, and didn't really provide any
  755.    value to the user (if anything, it created some confusion). The rule
  756.    now is that the use of an attibute that returns a value of some
  757.    particular type makes the compilation unit semantically dependent on
  758.    the library unit in which the type is declared (whether or not it is
  759.    "with"ed).
  760.  
  761.    The second place the Ripple effect came up was when we were trying to
  762.    provide automatic direct visibility to (primitive) operators.
  763.    Ultimately we ended up with an explicit "use type" clause for making
  764.    operators directly visible. For a while we considered various rules
  765.    that would make all primitive operators directly visible; some of the
  766.    rules considered created the undesirable "Ripple" effects; others
  767.    created annoying incompatibilities; all were quite tricky to implement
  768.    correctly and efficiently.
  769.  
  770.  
  771. 8.6: How to write an Ada program to compute when one has had too much alcohol
  772. to legally drive? 
  773.  
  774.    Someone asked if there is an Ada archive of this sort of program. Each
  775.    drink has a number of units of alcohol, max legal level, etc.
  776.  
  777.    (from Bob Kitzberger :-)
  778.  
  779.    Oh, this is much to vague. Don't touch that whizzy development
  780.    environment until you fully analyze the problem domain (unless that
  781.    whizzy development environment includes Rose, in which case, you get
  782.    to avoid paper and pencil from the git-go).
  783.  
  784.    Let's see, we have several classes to describe before we get to the
  785.    implementation:
  786.  
  787.    Person
  788.           subclass Drinker
  789.  
  790.           attributes: weight, age, timeline for amount consumed
  791.  
  792.    Drink
  793.           attributes: percentage of alcohol, quantity of drink
  794.  
  795.    Country
  796.           attributes: legal age to drink; max legal level of alcohol in
  797.           blood
  798.  
  799.  
  800.    Turn on the stereo, perhaps the Brandenburg Concertos. Then, flesh out
  801.    the domain classes. Then, have a Belgian beer and consider what to do
  802.    next. You decide on implementing these classes in a simple way,
  803.    leading to your first successful prototype. Then, have another beer
  804.    and decide what to do next. "Identify risk areas" you mutter to
  805.    yourself, and off you go...
  806.  
  807.    If the beer wasn't too strong, you'd probably realize that the only
  808.    thing of any difficulty in this is the amount consumed / rate of
  809.    decay. Decide on investigating this aspect further. Create
  810.    implementation classes for this and include a reference from the
  811.    Drinker class to this new timeline/decay Class. Have another beer.
  812.    Implement your second prototype. Congratulate yourself for making
  813.    progress so quickly.
  814.  
  815.    Have another beer. Wander over to the stereo and change the CD to
  816.    something more in the mood, maybe some Hendrix or Stevie Ray Vaughn.
  817.    Back in front of the computer; pop another beer. Decide that it would
  818.    be very cool if each drink was its own subclass of drink, and start
  819.    cataloguing every drink out of your "Pocket Bartender's Guide". Have a
  820.    slightly muddled epiphany that you really should create a class for
  821.    each kind of alcohol (vodka, tequila, etc.) and the individual drink
  822.    classes should each multiply inherit from all relevant Alcohol
  823.    classes. Ooh, this is going to be a bit rough, so you have another
  824.    beer. Draw a few of the hundreds of new class relationships needed,
  825.    put that on the back burner when you think "persistence! that's what's
  826.    missing!" Change the CD to Kraftwerk. Start your PPP connection, ask
  827.    the people on comp.object for recommendations on a good OODBMS to use
  828.    to keep track of all of those persistent objects. Make many many typos
  829.    in your posting; everyone ignores it. Fall asleep on the keyboard.
  830.  
  831.  
  832. 8.7: Does Ada have macros?
  833.  
  834.    No, neither Ada 83 nor Ada 95 do. There was a Steelman requirement
  835.    that the language developed NOT have a macro capability. This was a
  836.    well thought-out requirement. What you see in a piece of Ada code is
  837.    what you get (within a debugger for example). This does not hold true
  838.    for macro languages.
  839.  
  840.    General text-substitution macros like those in the C preprocessor are
  841.    thought to be too unsafe. For example, a macro can refer to a variable
  842.    X and depending where the macro is expanded X may or may not be
  843.    visible. Ada programs are supposed to be readable and in many cases C
  844.    macros are the main culprits in producing unreadable C programs.
  845.  
  846.    Compile time macro facilities tend to be dreadfully over- and misused,
  847.    resulting in horrible maintenance problems. Furthermore, there is a
  848.    tendency to use macros to patch up glaring omissions in the language.
  849.    For example, C has no named constants, a very bad omission, but
  850.    #define is used to patch over this gap.
  851.  
  852.    In C, three "legitimate" uses of macros are for defining compile-time
  853.    constants, types, and inline functions. Ada has all three of these
  854.    facilities, without macros.
  855.  
  856.    If one wants macros to handle conditional compilation, the better way
  857.    to achieve the equivalent is in most instances to isolate the system
  858.    dependent parts and then put them in separate units with multiple
  859.    system-specific implementations.
  860.